using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Interop;
using System.Runtime.InteropServices;
using CustomWindow;

namespace HomeMediaBrowser
{
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public partial class MainWindow : StandardWindow
    {
        //DWMHook
        [System.Runtime.InteropServices.DllImport("DwmHook.dll")]
        static extern void SetDwmWindowHook(int hWnd);

        //Windows API
        public const int WM_NCCALCSIZE = 131;
        public const int WM_NCHITTEST = 132;
        public const int WM_GETMINMAXINFO = 0x0024;
        public const int WM_MOUSEMOVE = 512;
        public const int WM_NCMOUSEMOVE = 160;
        public const int WM_NCPAINT = 133;
        /// WM_SIZE -> 0x0005
        public const int WM_SIZE = 5;
        /// WM_SIZING -> 0x0214
        public const int WM_SIZING = 532;
        /// SWP_NOSIZE -> 0x0001
        public const int SWP_NOSIZE = 1;
        /// SWP_FRAMECHANGED -> 0x0020
        public const int SWP_FRAMECHANGED = 32;

        const int GWL_EXSTYLE = -20;
        const int GWL_STYLE = -16;
        const int WS_EX_DLGMODALFRAME = 0x0001;

        /// WS_POPUP -> 0x80000000L
        public const int WS_POPUP = -2147483648;
        const int WS_BORDER = 0x00800000;
        const int WS_DLGFRAME = 0x00400000;
        const int WS_EX_COMPOSITED = 0x02000000;
        const int WS_CLIPSIBLINGS = 0x04000000;
        const int WS_CLIPCHILDREN = 0x02000000;

        public const int TRUE = 1;
        public const int FALSE = 0;

        /// WS_OVERLAPPEDWINDOW -> (WS_OVERLAPPED     |                              WS_CAPTION        |                              WS_SYSMENU        |                              WS_THICKFRAME     |                              WS_MINIMIZEBOX    |                              WS_MAXIMIZEBOX)
        public const int WS_OVERLAPPEDWINDOW = (WS_OVERLAPPED
                    | (WS_CAPTION
                    | (WS_SYSMENU
                    | (WS_THICKFRAME
                    | (WS_MINIMIZEBOX | WS_MAXIMIZEBOX)))));

        /// WS_OVERLAPPED -> 0x00000000L
        public const int WS_OVERLAPPED = 0;

        /// WS_CAPTION -> 0x00C00000L
        public const int WS_CAPTION = 12582912;

        /// WS_SYSMENU -> 0x00080000L
        public const int WS_SYSMENU = 524288;

        /// WS_THICKFRAME -> 0x00040000L
        public const int WS_THICKFRAME = 262144;

        /// WS_MINIMIZEBOX -> 0x00020000L
        public const int WS_MINIMIZEBOX = 131072;

        /// WS_MAXIMIZEBOX -> 0x00010000L
        public const int WS_MAXIMIZEBOX = 65536;

        /// HTBOTTOMRIGHT -> 17
        public const int HTBOTTOMRIGHT = 17;

        /// HTBOTTOMLEFT -> 16
        public const int HTBOTTOMLEFT = 16;

        /// HTTOPLEFT -> 13
        public const int HTTOPLEFT = 13;

        /// HTTOPRIGHT -> 14
        public const int HTTOPRIGHT = 14;

        /// HTCAPTION -> 2
        public const int HTCAPTION = 2;

        /// HTCLIENT -> 1
        public const int HTCLIENT = 1;

        /// HTNOWHERE -> 0
        public const int HTNOWHERE = 0;

        /// HTBORDER -> 18
        public const int HTBORDER = 18;

        /// HTBOTTOM -> 15
        public const int HTBOTTOM = 15;
        public const int HTCLOSE = 20;


        /// HTRIGHT -> 11
        public const int HTRIGHT = 11;

        /// HTLEFT -> 10
        public const int HTLEFT = 10;

        /// HTTOP -> 12
        public const int HTTOP = 12;


        [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
        public struct HWND__
        {
            /// int
            public int unused;
        }
        [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
        public struct tagRECT
        {

            /// LONG->int
            public int left;

            /// LONG->int
            public int top;

            /// LONG->int
            public int right;

            /// LONG->int
            public int bottom;
        }

        [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
        public struct tagMINMAXINFO
        {

            /// POINT->tagPOINT
            public Point ptReserved;

            /// POINT->tagPOINT
            public Point ptMaxSize;

            /// POINT->tagPOINT
            public Point ptMaxPosition;

            /// POINT->tagPOINT
            public Point ptMinTrackSize;

            /// POINT->tagPOINT
            public Point ptMaxTrackSize;
        }
        [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
        public struct Point
        {

            /// LONG->int
            public int x;

            /// LONG->int
            public int y;
        }
        [System.Runtime.InteropServices.DllImport("user32.dll", SetLastError = true)]
        static extern System.IntPtr DefWindowProcW(
            IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam
        );
        /// Return Type: HMONITOR->HMONITOR__*
        ///hwnd: HWND->HWND__*
        ///dwFlags: DWORD->unsigned int
        [System.Runtime.InteropServices.DllImportAttribute("user32.dll", EntryPoint = "MonitorFromWindow")]
        public static extern System.IntPtr MonitorFromWindow([System.Runtime.InteropServices.InAttribute()] System.IntPtr hwnd, uint dwFlags);


        /// Return Type: BOOL->int
        ///lpRect: LPRECT->tagRECT*
        ///dwStyle: DWORD->unsigned int
        ///bMenu: BOOL->int
        ///dwExStyle: DWORD->unsigned int
        [System.Runtime.InteropServices.DllImportAttribute("user32.dll", EntryPoint = "AdjustWindowRectEx")]
        [return: System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.Bool)]
        public static extern bool AdjustWindowRectEx(ref tagRECT lpRect, uint dwStyle, [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.Bool)] bool bMenu, uint dwExStyle);
        /// Return Type: BOOL->int
        ///hWnd: HWND->HWND__*
        ///lpRect: LPRECT->tagRECT*
        [System.Runtime.InteropServices.DllImportAttribute("user32.dll", EntryPoint = "GetWindowRect")]
        [return: System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.Bool)]
        public static extern bool GetWindowRect([System.Runtime.InteropServices.InAttribute()] System.IntPtr hWnd, [System.Runtime.InteropServices.OutAttribute()] out tagRECT lpRect);
        [DllImport("dwmapi.dll")]
        public static extern int DwmDefWindowProc(IntPtr hwnd, ushort msg, long wParam, long lParam, out int plResult);

        [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
        public struct tagNCCALCSIZE_PARAMS
        {

            /// RECT[3]
            [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst = 3, ArraySubType = System.Runtime.InteropServices.UnmanagedType.Struct)]
            public tagRECT[] rgrc;

            /// PWINDOWPOS->tagWINDOWPOS*
            public System.IntPtr lppos;
        }

        [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
        public struct tagWINDOWPOS
        {

            /// HWND->HWND__*
            public System.IntPtr hwnd;

            /// HWND->HWND__*
            public System.IntPtr hwndInsertAfter;

            /// int
            public int x;

            /// int
            public int y;

            /// int
            public int cx;

            /// int
            public int cy;

            /// UINT->unsigned int
            public uint flags;
        }


        [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
        public struct HDC__
        {

            /// int
            public int unused;
        }

        [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
        public struct HRGN__
        {

            /// int
            public int unused;
        }
        /// Return Type: HDC->HDC__*
        ///hWnd: HWND->HWND__*
        ///hrgnClip: HRGN->HRGN__*
        ///flags: DWORD->unsigned int
        [System.Runtime.InteropServices.DllImportAttribute("user32.dll", EntryPoint = "GetDCEx")]
        public static extern System.IntPtr GetDCEx([System.Runtime.InteropServices.InAttribute()] System.IntPtr hWnd, [System.Runtime.InteropServices.InAttribute()] System.IntPtr hrgnClip, uint flags);
        /// Return Type: int
        ///hdc: HDC->HDC__*
        ///lpchText: LPCWSTR->WCHAR*
        ///cchText: int
        ///lprc: LPRECT->tagRECT*
        ///format: UINT->unsigned int
        [System.Runtime.InteropServices.DllImportAttribute("user32.dll", EntryPoint = "DrawTextW")]
        public static extern int DrawTextW([System.Runtime.InteropServices.InAttribute()] System.IntPtr hdc, [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPWStr)] System.Text.StringBuilder lpchText, int cchText, ref tagRECT lprc, uint format);

        /// Return Type: HDC->HDC__*
        ///hWnd: HWND->HWND__*
        [System.Runtime.InteropServices.DllImportAttribute("user32.dll", EntryPoint = "GetWindowDC")]
        public static extern System.IntPtr GetWindowDC([System.Runtime.InteropServices.InAttribute()] System.IntPtr hWnd);

        [DllImport("user32.dll")]
        static extern int GetWindowLong(IntPtr hwnd, int index);
        [DllImport("user32.dll")]
        static extern int SetWindowLong(IntPtr hwnd, int index, int newStyle);
        [DllImport("user32.dll")]
        static extern bool SetWindowPos(IntPtr hwnd, IntPtr hwndInsertAfter, int x, int y, int width, int height, uint flags);
        [DllImport("user32.dll")]
        static extern IntPtr SendMessage(IntPtr hwnd, uint msg, IntPtr wParam, IntPtr lParam);

        private void SetWindowThemeAttribute(Window window, bool showCaption, bool showIcon)
        {
            bool isGlassEnabled = AeroHelper.DwmApi.DwmIsCompositionEnabled();

            IntPtr hwnd = new WindowInteropHelper(window).Handle;

            var options = new AeroHelper.DwmApi.WTA_OPTIONS
            {
                dwMask = (AeroHelper.DwmApi.WTNCA_NODRAWCAPTION | AeroHelper.DwmApi.WTNCA_NODRAWICON)
            };
            if (isGlassEnabled)
            {
                if (!showCaption)
                {
                    options.dwFlags |= AeroHelper.DwmApi.WTNCA_NODRAWCAPTION;
                }
                if (!showIcon)
                {
                    options.dwFlags |= AeroHelper.DwmApi.WTNCA_NODRAWICON;
                }
            }

            AeroHelper.SetWindowThemeAttribute(hwnd, AeroHelper.DwmApi.WindowThemeAttributeType.WTA_NONCLIENT, ref options, (uint)Marshal.SizeOf(typeof(AeroHelper.DwmApi.WTA_OPTIONS)));
        }
    }



    // API ShellExecuteW
    [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
    public struct HINSTANCE__
    {

        /// int
        public int unused;
    }

    [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
    public struct HWND__
    {

        /// int
        public int unused;
    }

    public partial class NativeMethods
    {

        /// Return Type: HINSTANCE->HINSTANCE__*
        ///hwnd: HWND->HWND__*
        ///lpOperation: LPCTSTR->LPCWSTR->WCHAR*
        ///lpFile: LPCTSTR->LPCWSTR->WCHAR*
        ///lpParameters: LPCTSTR->LPCWSTR->WCHAR*
        ///lpDirectory: LPCTSTR->LPCWSTR->WCHAR*
        ///nShowCmd: INT->int
        [System.Runtime.InteropServices.DllImportAttribute("shell32.dll", EntryPoint = "ShellExecuteW")]
        public static extern System.IntPtr ShellExecuteW(System.IntPtr hwnd, [System.Runtime.InteropServices.InAttribute()] [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPTStr)] string lpOperation, [System.Runtime.InteropServices.InAttribute()] [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPTStr)] string lpFile, [System.Runtime.InteropServices.InAttribute()] [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPTStr)] string lpParameters, [System.Runtime.InteropServices.InAttribute()] [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPTStr)] string lpDirectory, int nShowCmd);

    }
}